package com.orm.handler;


import java.lang.reflect.Type;
import java.math.BigInteger;
import java.sql.JDBCType;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 所有类型处理器都在这里注册
 */
public final class TypeHandlerRegister {
	
	// jdbc枚举类型 -> java 类型，用来取值
	private final Map<JDBCType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new HashMap<>();
	
	
	// private final Map<Class<?>,Map<JDBCType,TypeHandler<?>>> TYPE_HANDLER_MAP=new HashMap<>();
	
	
	// java 类型  ->  处理器
	private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<>();
	
	
	public TypeHandlerRegister() {
		// boolean
		register(boolean.class, new BooleanTypeHandler());
		register(Boolean.class, new BooleanTypeHandler());
		
		// int
		IntegerTypeHandler integerTypeHandler = new IntegerTypeHandler();
		register(int.class, integerTypeHandler);
		register(Integer.class, integerTypeHandler);
		register(JDBCType.INTEGER, integerTypeHandler);
		
		// long
		LongTypeHandler longTypeHandler = new LongTypeHandler();
		register(long.class, longTypeHandler);
		register(Long.class, longTypeHandler);
		
		// float
		FloatTypeHandler floatTypeHandler = new FloatTypeHandler();
		register(float.class, floatTypeHandler);
		register(Float.class, floatTypeHandler);
		register(JDBCType.FLOAT, floatTypeHandler);
		
		// double
		DoubleTypeHandler doubleTypeHandler = new DoubleTypeHandler();
		register(double.class, doubleTypeHandler);
		register(Double.class, doubleTypeHandler);
		register(JDBCType.DOUBLE, doubleTypeHandler);
		
		// string
		StringTypeHandler stringTypeHandler = new StringTypeHandler();
		register(String.class, stringTypeHandler);
		register(JDBCType.CHAR, stringTypeHandler);
		register(JDBCType.VARCHAR, stringTypeHandler);
		
		// bigint
		BigIntegerTypeHandler bigIntegerTypeHandler = new BigIntegerTypeHandler();
		register(BigInteger.class, bigIntegerTypeHandler);
		register(JDBCType.BIGINT, bigIntegerTypeHandler);
		
		
		// date  util和sql 包下
		register(Date.class, new DateTypeHandler());
		register(java.sql.Date.class, new SqlDateTypeHandler());
		
		// time
		register(Time.class, new SqlTimeTypeHandler());
		
		// timestamp
		register(Timestamp.class, new SqlTimestampTypeHandler());
		
		
		// java8 日期时间
		register(LocalDateTime.class, new LocalDateTimeTypeHandler());
		register(LocalDate.class, new LocalDateTypeHandler());
		register(LocalTime.class, new LocalTimeTypeHandler());
		register(Instant.class, new InstantTypeHandler());
		
		
		// Object
		register(Object.class,new ObjectTypeHandler());
		
	}
	
	public void register(JDBCType type, TypeHandler<?> handler) {
		JDBC_TYPE_HANDLER_MAP.put(type, handler);
	}
	
	public <T> void register(Class<T> type, TypeHandler<? extends T> handler) {
		ALL_TYPE_HANDLERS_MAP.put(type, handler);
	}
	
	// 用不到
	public TypeHandler<?> getTypeHandler(JDBCType type) {
		return JDBC_TYPE_HANDLER_MAP.get(type);
	}
	
	@SuppressWarnings({"rawtypes", "unchecked"})
	public <T> TypeHandler<T> getTypeHandler(Class<?> type) {
		return (TypeHandler<T>) ALL_TYPE_HANDLERS_MAP.get(type);
	}
	
	
	private static TypeHandlerRegister register = new TypeHandlerRegister();
	
	public static TypeHandlerRegister newInstance() {
		return register;
	}
}
